package com.zkzx.freight.bill.service;

import com.zkzx.common.freight.command.OrderCommand;
import com.zkzx.common.freight.model.OrderListVO;
import com.zkzx.common.freight.model.OrderVO;
import com.zkzx.common.freight.param.OrderFilterParam;
import com.zkzx.common.freight.vo.OrderStatisticsVO;
import com.zkzx.common.global.Global;
import com.zkzx.common.vo.PageResult;
import com.zkzx.common.vo.RequestFilterParams;
import com.zkzx.common.vo.StatusVO;
import com.zkzx.freight.bill.mapper.OrderMapper;
import com.zkzx.freight.bill.mapper.entity.Order;
import com.zkzx.freight.bill.mapper.entity.OrderExample;
import com.zkzx.common.freight.constants.OrderStatusEnum;
import com.zkzx.util.config.PrimaryMarkUtil;
import com.zkzx.util.sql.SQLUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 北京中科智兴物联科技有限公司 @版权所有
 * @Author: zhaoyihe@zkraising.com
 * @Date: 2021/05/12/17:52
 * @Description:
 */
@Slf4j
@Service
public class OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Autowired
    private OrderDeliveryService orderDeliveryService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private OrderPayableService orderPayableService;

    @Autowired
    private OrderLogisticsService orderLogisticsService;

    /**
     * 分页查询订单数据
     * @param filterParam 查询条件
     * @param params 分页参数
     * @return 订单分页数据
     */
    public PageResult<OrderListVO> find(OrderFilterParam filterParam, RequestFilterParams params) {

        OrderExample orderExample = new OrderExample();
        OrderExample.Criteria criteria = orderExample.createCriteria();


        if(StringUtils.isNotBlank(filterParam.getCode())){
            criteria.andCidLike(SQLUtil.valueBuildLike(filterParam.getCode()));
        }
        if(StringUtils.isNotBlank(filterParam.getDriverName())){
            criteria.andDrivernameLike(SQLUtil.valueBuildLike(filterParam.getDriverName()));
        }

        if(StringUtils.isNotBlank(filterParam.getTruckCode())){
            criteria.andTruckcodeLike(SQLUtil.valueBuildLike(filterParam.getTruckCode()));
        }
        if(StringUtils.isNotBlank(filterParam.getStatus())){
            criteria.andStatusEqualTo(filterParam.getStatus());
        }

        if (null != filterParam.getCompanyId()){
            criteria.andCompanyidEqualTo(filterParam.getCompanyId());
        }
        long totalNum = orderMapper.countByExample(orderExample);

        if (totalNum <= Global.ZERO){
            return new PageResult<>(params.getPage(),params.getPerPage(), Collections.emptyList(), Global.ZERO);
        }



        orderExample.setOrderByClause(params.getField().concat(" ").concat(params.getOrder()));
        orderExample.page(params.getPage()-Global.ONE , params.getPerPage());
        List<Order> orders = orderMapper.selectByExample(orderExample);

        List<OrderListVO> list=orders.stream().map(order -> OrderListVO.builder()
                .id(order.getId())
                .cid(order.getCid())
                .code(order.getCode())
                .companyId(order.getCompanyid())
                .driverId(order.getDriverid())
                .driverName(order.getDrivername())
                .truckId(order.getTruckid())
                .truckCode(order.getTruckcode())
                .orderDeliveryVO(orderDeliveryService.findVOByOrderIdId(order.getId()))
                .orderItemVO(orderItemService.findVOByOrderIdId(order.getId()))
                .orderPayableVO(orderPayableService.findVOByOrderIdId(order.getId()))
                .submitTime(order.getSubmittime())
                .statusVO(StatusVO.builder()
                        .value(OrderStatusEnum.valueOf(order.getStatus()).name())
                        .description(OrderStatusEnum.valueOf(order.getStatus()).getDescription())
                        .context(order.getReason())
                        .build())
                .build()).collect(Collectors.toList());

        return new PageResult<>(params.getPage(),params.getPerPage(),list, (int) totalNum);
    }



    /**
     * 根据id获取订单信息
     * @param id 订单id
     * @return 订单详情信息
     */
    public OrderVO getById(Integer id){
        Order order = orderMapper.selectByPrimaryKey(id);
        if(Objects.isNull(order)){
            return null;
        }
        return OrderVO.builder()
                .id(id)
                .cid(order.getCid())
                .companyId(order.getCompanyid())
                .code(order.getCode())
                .escortPic(order.getEscortpic())
                .loadPic(order.getLoadpic())
                .signPic(order.getSignpic())
                .dischargePic(order.getDischargepic())
                .driverId(Integer.parseInt(order.getDriverid()))
                .truckId(Integer.parseInt(order.getTruckid()))
                .insuranceCode(order.getInsurancecode())
                .overrunPic(order.getOverrunpic())
                .remark(order.getRemark())
                .reason(order.getReason())
                .createTime(order.getCreatetime())
                .statusVO(StatusVO.builder()
                        .value(OrderStatusEnum.valueOf(order.getStatus()).name())
                        .description(OrderStatusEnum.valueOf(order.getStatus()).getDescription())
                        .build())
                .orderItemVO(orderItemService.findVOByOrderIdId(order.getId()))
                .orderDeliveryVO(orderDeliveryService.findVOByOrderIdId(order.getId()))
                .orderLogisticss(orderLogisticsService.findVOByOrderIdId(order.getId()))
                .orderPayableVO(orderPayableService.findVOByOrderIdId(order.getId()))
                .build();
    }


    /**
     * 新增运单信息
     * @param command 入参
     * @param userId 用户id
     */
    public StatusVO add(OrderCommand command, int userId){

        Order order = new Order();
        order.setCid(PrimaryMarkUtil.getYDMark());
        order.setCompanyid(command.getCompanyId());
        order.setCode(command.getCode());
        order.setEscortpic(command.getEscortPic());
        order.setLoadpic(command.getLoadPic());
        order.setSignpic(command.getSignPic());
        order.setDischargepic(command.getDischargePic());
        order.setDriverid(command.getDriverId());
        order.setDrivername(command.getDriverName());
        order.setTruckid(command.getTruckId());
        order.setTruckcode(command.getTruckCode());
        order.setInsurancecode(command.getInsuranceCode());
        order.setOverrunpic(command.getOverrunPic());
        order.setRemark(command.getRemark());
        order.setStatus(StringUtils.isBlank(command.getStatus()) ? OrderStatusEnum.NO_SUBMIT.name(): command.getStatus());
        order.setReason(command.getReason());
        order.setCreatetime(new Date());
        order.setLastmodifiedtime(new Date());
        order.setCreateuser(userId);
        order.setLastmodifieduser(userId);

        orderMapper.insertSelective(order);

        OrderExample orderExample = new OrderExample();
        orderExample.createCriteria().andCidEqualTo(order.getCid());
        Optional<Order> first = orderMapper.selectByExample(orderExample).stream().findFirst();
        Integer id = 0;
        if(first.isPresent()){
            id= first.get().getId();
        }
        //插入货物信息
        orderItemService.insert(command,id);
        //插入发货方，收货方信息
        orderDeliveryService.insert(command,id);
        //插入运输费用
        orderPayableService.insert(command,id);
        //插入运单轨迹
        orderLogisticsService.insert(command,id);
        return StatusVO.builder().id(id).value(OrderStatusEnum.valueOf(order.getStatus()).name())
                .description(OrderStatusEnum.valueOf(order.getStatus()).getDescription()).build();
    }

    /**
     * 更新运单信息
     * @param command 入参
     * @param id 运单id
     * @param userId 登录人id
     */
    public void update(OrderCommand command, Integer id, int userId) {
        Order order = new Order();

        order.setCode(command.getCode());
        order.setEscortpic(command.getEscortPic());
        order.setLoadpic(command.getLoadPic());
        order.setSignpic(command.getSignPic());
        order.setDischargepic(command.getDischargePic());
        order.setDriverid(command.getDriverId());
        order.setDrivername(command.getDriverName());
        order.setTruckid(command.getTruckId());
        order.setTruckcode(command.getTruckCode());
        order.setSubmittime(command.getSubmitTime());
        order.setInsurancecode(command.getInsuranceCode());
        order.setOverrunpic(command.getOverrunPic());
        order.setRemark(command.getRemark());
        order.setStatus(StringUtils.isBlank(command.getStatus()) ? OrderStatusEnum.NO_SUBMIT.name(): command.getStatus());
        order.setReason(command.getReason());
        order.setLastmodifiedtime(new Date());
        order.setLastmodifieduser(userId);

        OrderExample orderExample = new OrderExample();
        OrderExample.Criteria criteria = orderExample.createCriteria();
        criteria.andIdEqualTo(id);
        orderMapper.updateByExampleSelective(order,orderExample);

        //更新货物信息
        orderItemService.update(command,id);
        //更新发货方，收货方信息
        orderDeliveryService.update(command,id);
        //更新运输费用
        orderPayableService.update(command,id);
        //更新运单轨迹
        orderLogisticsService.update(command,id);

    }

    /**
     * 查询订单统计数据
     * @param companyId 入参
     */
   public OrderStatisticsVO getOrderStatistics(Integer companyId){

       int orderNum = getOrderNum(companyId);
       int unpaidNum = getUnpaidNum(companyId);
       int errorNum = getErrorNum(companyId);
       int invoiceNum = getInvoiceNum(companyId);
       return OrderStatisticsVO.builder()
               .orderNum(orderNum)
               .invoiceOrderNum(invoiceNum)
               .unpaidOrderNum(unpaidNum)
               .errorOrderNum(errorNum)
               .build();

   }
    /**
     * 查询订单总数量
     * 已提交的所有状态运单总数
     * @param companyId 订单总数量
     */
    public int getOrderNum(Integer companyId){
        OrderExample orderExample = new OrderExample();
        OrderExample.Criteria criteria = orderExample.createCriteria();
        criteria.andCompanyidEqualTo(companyId);

        List<String> orderNumList = new ArrayList<>();
        orderNumList.add(OrderStatusEnum.APPROVE_WAIT.name());
        orderNumList.add(OrderStatusEnum.PLATFORM_REJECT.name());
        orderNumList.add(OrderStatusEnum.PAY_WAIT.name());
        orderNumList.add(OrderStatusEnum.PAY_ING.name());
        orderNumList.add(OrderStatusEnum.PAY_INVOICE.name());
        orderNumList.add(OrderStatusEnum.INVOICING.name());
        orderNumList.add(OrderStatusEnum.NO_INVOICED.name());
        orderNumList.add(OrderStatusEnum.CAN_INVOICING.name());
        orderNumList.add(OrderStatusEnum.INVOICED.name());
        criteria.andStatusNotIn(orderNumList);

        long orderNum = orderMapper.countByExample(orderExample);

        return (int)orderNum;
    }

    /**
     * 查询未支付订单数量
     * @param companyId 未支付订单数量
     */
    public int getUnpaidNum(Integer companyId){
       OrderExample orderExample = new OrderExample();
       OrderExample.Criteria criteria = orderExample.createCriteria();
       criteria.andCompanyidEqualTo(companyId);
       criteria.andStatusEqualTo(OrderStatusEnum.PAY_WAIT.name());
       long unpaidNum = orderMapper.countByExample(orderExample);

       return (int)unpaidNum;

   }

    /**
     * 查询异常订单数量
     * 账号下异常状态运单总数
     * @param companyId 异常订单数量
     */
    public int getErrorNum(Integer companyId){
        OrderExample orderExample = new OrderExample();
        OrderExample.Criteria criteria = orderExample.createCriteria();
        criteria.andCompanyidEqualTo(companyId);
        criteria.andStatusEqualTo(OrderStatusEnum.PLATFORM_REJECT.name());
        long errorNum = orderMapper.countByExample(orderExample);

        return (int)errorNum;
    }
    /**
     * 查询待开票订单数量
     * @param companyId 开票订单数量
     */
    public int getInvoiceNum(Integer companyId){
        OrderExample orderExample = new OrderExample();
        OrderExample.Criteria criteria = orderExample.createCriteria();
        criteria.andCompanyidEqualTo(companyId);

        criteria.andStatusEqualTo(OrderStatusEnum.PAY_INVOICE.name());
        long invoiceNum = orderMapper.countByExample(orderExample);
        return (int)invoiceNum;
    }
}
